package com.sprucetec.live.service.impl;

import com.sprucetec.live.common.dto.business.LiveUserDto;
import com.sprucetec.live.common.dto.business.LiveVideoDto;
import com.sprucetec.live.constants.MqConstant;
import com.sprucetec.live.constants.RedisKeyConstant;
import com.sprucetec.live.entity.LiveOnlineUser;
import com.sprucetec.live.entity.LiveVideo;
import com.sprucetec.live.entity.LiveVideoData;
import com.sprucetec.live.mapper.LiveVideoDataMapper;
import com.sprucetec.live.service.LiveOnlineUserService;
import com.sprucetec.live.service.LiveVideoDataService;
import com.sprucetec.live.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisUtils;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import tk.mybatis.mapper.entity.Example;

import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName LiveVideoDataServiceImpl
 * @Description:
 * @Author Kenny
 * @Date 2020/4/5
 **/
@Slf4j
@Service("liveVideoDataService")
public class LiveVideoDataServiceImpl implements LiveVideoDataService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LiveVideoDataMapper liveVideoDataMapper;
    @Autowired
    private RedisUtil redisUtil;

    private static final Long expireSeconds = 60 * 60 * 12L; // 12小时超时

    @Autowired
    private LiveOnlineUserService liveOnlineUserService;

    /**
     * 关闭直播进行数据统计， 相关缓存设置超时时间
     *
     * @param liveVideoDto
     */
    @Override
    public void statisticalVideoData(LiveVideoDto liveVideoDto) {
        String chatKey = RedisKeyConstant.LiveChat.LIVE_CHAT_CACHE + ":videoId:" + liveVideoDto.getId() + ":type:0";
        String questionKey = RedisKeyConstant.LiveChat.LIVE_CHAT_CACHE + ":videoId:" + liveVideoDto.getId() + ":type:1";
        String watchNumKey = RedisKeyConstant.LiveVideoDataStatistics.watchNum + liveVideoDto.getLiveNo();
        String onlineUserKey = RedisKeyConstant.LiveVideoDataStatistics.onlineUser + liveVideoDto.getLiveNo();
        String topNumKey = RedisKeyConstant.LiveVideoDataStatistics.topNum + liveVideoDto.getLiveNo();
        /**
         * 先清空
         */
        // 清空视频数据
        Example example = new Example(LiveVideoData.class);
        example.createCriteria().andEqualTo("liveVideoId", liveVideoDto.getId());
        liveVideoDataMapper.deleteByExample(example);
        // 清空在线人
        Example userExample = new Example(LiveOnlineUser.class);
        userExample.createCriteria().andEqualTo("relateVideoNo", liveVideoDto.getLiveNo());
        liveOnlineUserService.clearUserByCondition(userExample);

        /**
         * 再添加
         */
        // 在线人
        LiveVideoData liveVideoData = new LiveVideoData();
        List<LiveUserDto> onlineUsers = redisTemplate.boundHashOps(RedisKeyConstant.LiveVideoDataStatistics.onlineUser + liveVideoDto.getLiveNo()).values();
        List<LiveOnlineUser> liveOnlineUsers = new ArrayList<>();
        onlineUsers.forEach((onlineUser) -> {
            LiveOnlineUser liveOnlineUser = new LiveOnlineUser();
            BeanUtils.copyProperties(onlineUser, liveOnlineUser);
            liveOnlineUser.setRelateVideoNo(onlineUser.getLiveNo());
            liveOnlineUsers.add(liveOnlineUser);
        });
        liveOnlineUserService.batchInsert(liveOnlineUsers);

        // 峰值人数
        String topNum = redisTemplate.boundValueOps(topNumKey).get(0, -1);
        liveVideoData.setOnLineNum(Long.valueOf(onlineUsers.size()));

        // 观看次数
        String watchNum = redisTemplate.boundValueOps(watchNumKey).get(0, -1);
        if (StringUtils.isNotBlank(topNum)) {
            liveVideoData.setTopLineNum(Long.parseLong(topNum));
        }
        liveVideoData.setLiveVideoId(liveVideoDto.getId());
        if (StringUtils.isNotBlank(watchNum)) {
            liveVideoData.setWatchNum(Long.parseLong(watchNum));
        }
        // 聊天人数
        Long chatPersonNum = redisTemplate.boundSetOps(RedisKeyConstant.LiveVideoDataStatistics.chatPersonNum + liveVideoDto.getLiveNo()).size();
        liveVideoData.setChatPersonNum(chatPersonNum);

        // 聊天次数
        BoundValueOperations boundValueOperations = redisTemplate.boundValueOps(RedisKeyConstant.LiveVideoDataStatistics.chatNum + liveVideoDto.getLiveNo());
        if (boundValueOperations.get() != null) {
            liveVideoData.setChatCountNum(((Integer) boundValueOperations.get()).longValue());
        }

        //提问人数
        Long questionPersonNum = redisTemplate.boundSetOps(RedisKeyConstant.LiveVideoDataStatistics.questionPersonNum + liveVideoDto.getLiveNo()).size();
        liveVideoData.setQuestionPersonNum(questionPersonNum);

        // 提问次数
        BoundValueOperations bQuestion = redisTemplate.boundValueOps(RedisKeyConstant.LiveVideoDataStatistics.questionNum + liveVideoDto.getLiveNo());
        if (bQuestion.get() != null) {
            liveVideoData.setQuestionCountNum(((Integer) bQuestion.get()).longValue());
        }

        liveVideoDataMapper.insertSelective(liveVideoData);
        // 设置相关redis缓存， 设置超时时间，降低redis服务器存储过多数据的压力
        // 关闭直播后redis 一个小时之后清空直播相关缓存, 节省redis内存空间
        redisUtil.expire(chatKey, expireSeconds, TimeUnit.SECONDS);
        redisUtil.expire(questionKey, expireSeconds, TimeUnit.SECONDS);
        redisUtil.expire(topNumKey, expireSeconds, TimeUnit.SECONDS);
        redisUtil.expire(onlineUserKey, expireSeconds, TimeUnit.SECONDS);
        redisUtil.expire(watchNumKey, expireSeconds, TimeUnit.SECONDS);
        // 关闭直播 在线人数值为空
        redisUtil.delete(MqConstant.ChatMq.onlineUserNum + liveVideoDto.getId());
    }

    @Override
    public LiveVideoData getLiveVideoData(LiveVideo liveVideo) {
        Long onLineNum = redisTemplate.boundHashOps(RedisKeyConstant.LiveVideoDataStatistics.onlineUser + liveVideo.getLiveNo()).size();
        String topNum = redisTemplate.boundValueOps(RedisKeyConstant.LiveVideoDataStatistics.topNum + liveVideo.getLiveNo()).get(0, -1);
        String watchNum = redisTemplate.boundValueOps(RedisKeyConstant.LiveVideoDataStatistics.watchNum + liveVideo.getLiveNo()).get(0, -1);
        Long chatPersonNum = redisTemplate.boundSetOps(RedisKeyConstant.LiveVideoDataStatistics.chatPersonNum + liveVideo.getLiveNo()).size();// 聊天人数
        Long chatNum = redisTemplate.boundValueOps(RedisKeyConstant.LiveVideoDataStatistics.chatNum + liveVideo.getLiveNo()).size();
        Long questionPersonNum = redisTemplate.boundSetOps(RedisKeyConstant.LiveVideoDataStatistics.questionPersonNum + liveVideo.getLiveNo()).size();
        Long questionNum = redisTemplate.boundValueOps(RedisKeyConstant.LiveVideoDataStatistics.questionNum + liveVideo.getLiveNo()).size(); // 提问人数
        LiveVideoData liveVideoData = new LiveVideoData();
        liveVideoData.setOnLineNum(onLineNum);
        liveVideoData.setTopLineNum(StringUtils.isNotBlank(topNum) ? Long.parseLong(topNum) : 0);
        liveVideoData.setWatchNum(StringUtils.isNotBlank(watchNum) ? Long.parseLong(watchNum) : 0);
        liveVideoData.setChatPersonNum(chatPersonNum);
        liveVideoData.setChatCountNum(chatNum);
        liveVideoData.setQuestionPersonNum(questionPersonNum);
        liveVideoData.setQuestionCountNum(questionNum);
        return liveVideoData;
    }

}
